package net.jacqeush.mini.rpc.handler;

import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;


import io.netty.channel.SimpleChannelInboundHandler;
import lombok.Getter;
import lombok.Setter;
import net.jacqeush.mini.rpc.client.manage.RpcFuture;

import net.jacqeush.mini.rpc.codec.model.Request;
import net.jacqeush.mini.rpc.codec.model.Response;
import org.apache.commons.lang.StringUtils;

import java.net.SocketAddress;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author Jacquesh
 * @version 1.0
 * @date 2020/10/15 17:20
 */
@Getter
@Setter
public class RpcClientHandler extends SimpleChannelInboundHandler<Response> {

    private Map<String , RpcFuture> pendingRpcTable = new ConcurrentHashMap<String, RpcFuture>();
    private Channel netChannel;
    private SocketAddress remote;
    private volatile boolean yes=false;
    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        this.netChannel=ctx.channel();
        this.remote=ctx.channel().remoteAddress();
        super.channelRegistered(ctx);

    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        this.yes=true;
        this.remote=ctx.channel().remoteAddress();
        super.channelActive(ctx);

    }

    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, Response response) {
        String requestId = response.getRequestId();

        if (StringUtils.isNotBlank(requestId)){
           RpcFuture rpcFuture= pendingRpcTable.get(requestId);

            if(rpcFuture!=null){
                rpcFuture.done(response);
            }
            pendingRpcTable.remove(rpcFuture);
        }

    }


    public void close() {

        netChannel.writeAndFlush(Unpooled.EMPTY_BUFFER).addListener(ChannelFutureListener.CLOSE);
    }

    public RpcFuture sendRequest(Request request) {
        RpcFuture rpcFuture = new RpcFuture(request);
        pendingRpcTable.put(request.getRequestId(), rpcFuture);
        netChannel.writeAndFlush(request);
        return rpcFuture;
    }

    public boolean getSuccess() {
        return yes;
    }


}
